/**
  ******************************************************************************
  * @file    Project/STM32F10x_StdPeriph_Template/main.c 
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */  

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "led.h"
#include "spi_flash.h"
#include "usart.h"
#include "usart_stdio.h"
#include "base_timer.h"
#include "keyboard.h"
#include "ssd1306_spi.h"
#include "screen.h"
#include "trigger_flags.h"
#include "rtc.h"

#include "SGUI_Typedef.h"
#include "SGUI_Text.h"
#include "SGUI_FontResource.h"

void ConfigRTC(void);
void TimerEventProc(void);

char		szTextBuffer[64];

int main(void)
{
	bool			bExit = true;;
	SGUI_SCR_DEV	stDeviceInterface = {0x00};
	SGUI_RECT		stDisplayArea;
	SGUI_POINT		stPos;
	RTC_CALENDAR_STRUCT* pstNowTime;
	uint16_t		uiKeyCode;

	/* Initialize screen device. */
	SCREEN_Initialize();
	SCREEN_ClearDisplay();
	/* Display initialize info. */
	stDeviceInterface.stSize.iWidth = 128;
	stDeviceInterface.stSize.iHeight = 64;
	stDeviceInterface.fnClear = SCREEN_ClearDisplay;
	stDeviceInterface.fnGetPixel = SCREEN_GetPixel;
	stDeviceInterface.fnSetPixel = SCREEN_SetPixel;
	stDeviceInterface.fnInitialize = SCREEN_Initialize;
	stDeviceInterface.fnSyncBuffer = SCREEN_RefreshScreen;
	
	stDisplayArea.iPosX = 0;
	stDisplayArea.iPosY = 0;
	stDisplayArea.iWidth = 94;
	stDisplayArea.iHeight = 8;
	stPos.iPosX = 0;
	stPos.iPosY = 0;
	
	SGUI_Text_DrawText(&stDeviceInterface, "1.Screen init.", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	
	stDisplayArea.iPosX = 96;
	stDisplayArea.iWidth = 24;
#ifdef SSD1306_SOFT_SPI
	SGUI_Text_DrawText(&stDeviceInterface, "soft", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
#else
	SGUI_Text_DrawText(&stDeviceInterface, "hard", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
#endif
	stDeviceInterface.fnSyncBuffer();
	
	/* Initialize usart 1 for stdio. */
	stDisplayArea.iPosX = 0;
	stDisplayArea.iPosY += 8;
	stDisplayArea.iWidth = 94;
	SGUI_Text_DrawText(&stDeviceInterface, "2.STD io init.", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	USART_Stdio_Initialize(115200);
	printf("Stand IO initialized.\r\n");
	USART1_ConfigReceiveInterrupt(USARTReceiveProc, 2, 2);
	USART_ActiveInterrupt(USART1, true);
	stDisplayArea.iPosX = 96;
	stDisplayArea.iWidth = 24;
	SGUI_Text_DrawText(&stDeviceInterface, "done", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	
	/* Initialize SPI flash */
	stDisplayArea.iPosX = 0;
	stDisplayArea.iPosY += 8;
	stDisplayArea.iWidth = 94;
	SGUI_Text_DrawText(&stDeviceInterface, "3.Flash init.", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	SPI_FLASH_Initialize();
	printf("SPI flash initialized.\r\n");
	stDisplayArea.iPosX = 96;
	stDisplayArea.iWidth = 24;
	SGUI_Text_DrawText(&stDeviceInterface, "done", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	
	/* Initialize LED and turn off. */
	stDisplayArea.iPosX = 0;
	stDisplayArea.iPosY += 8;
	stDisplayArea.iWidth = 94;
	SGUI_Text_DrawText(&stDeviceInterface, "4.LED init.", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	LED_Initialize();
	printf("LED initialized.\r\n");
	LED_Off();
	stDisplayArea.iPosX = 96;
	stDisplayArea.iWidth = 24;
	SGUI_Text_DrawText(&stDeviceInterface, "done", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	
	/* Initialize RTC and interrupt. */
	stDisplayArea.iPosX = 0;
	stDisplayArea.iPosY += 8;
	stDisplayArea.iWidth = 94;
	SGUI_Text_DrawText(&stDeviceInterface, "5.RTC init.", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	RTC_Initialize();
	RTC_ConfigReceiveInterrupt(RTCInterruptProc, 0, 0);
	printf("RTC initialized.\r\n");
	stDisplayArea.iPosX = 96;
	stDisplayArea.iWidth = 24;
	SGUI_Text_DrawText(&stDeviceInterface, "done", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();

	/* Initialize base timer. */
	stDisplayArea.iPosX = 0;
	stDisplayArea.iPosY += 8;
	stDisplayArea.iWidth = 94;
	SGUI_Text_DrawText(&stDeviceInterface, "6.Timer init.", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	BASE_TIMER_Initialize(TIM3, 4999, 7199);
	TIM3_ConfigReceiveInterrupt(TimerEventProc, 2, 2);
	BASE_TIMER_ActiveInterrupt(TIM3, true);
	printf("General timer initialized.\r\n");
	stDisplayArea.iPosX = 96;
	stDisplayArea.iWidth = 24;
	SGUI_Text_DrawText(&stDeviceInterface, "done", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	
	/* Initialize key board. */
	stDisplayArea.iPosX = 0;
	stDisplayArea.iPosY += 8;
	stDisplayArea.iWidth = 94;
	SGUI_Text_DrawText(&stDeviceInterface, "7.Keyboard init.", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	KB_Initialize();
	KB_RegisterEventProc(KeyEventProc);
	printf("Key board initialized.\r\n");
	stDisplayArea.iPosX = 96;
	stDisplayArea.iWidth = 24;
	SGUI_Text_DrawText(&stDeviceInterface, "done", &SGUI_DEFAULT_FONT_8, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();

	/* Wait for one time RTC interrupt. */
	while(false == RTCTimerIsTrigger())
	{
		/* Waiting, do nothing. */
		RTCTimerTriggerReset();
	}
	
	/* Clear screen display. */
	stDeviceInterface.fnClear();
	SGUI_Basic_DrawRectangle(&stDeviceInterface, 0, 0, stDeviceInterface.stSize.iWidth, stDeviceInterface.stSize.iHeight, SGUI_COLOR_FRGCLR, SGUI_COLOR_BKGCLR);
	
	stDisplayArea.iPosX = 2;
	stDisplayArea.iPosY = 2;
	stDisplayArea.iWidth = 124;
	stDisplayArea.iHeight = 12;
	stPos.iPosX = 0;
	stPos.iPosY = 0;
	
	/* SPI flash ID. */
	szTextBuffer[0] = '\0';
	sprintf(szTextBuffer, "Flash ID: %06X", SPI_FLASH_ReadID());
	SGUI_Text_DrawText(&stDeviceInterface, szTextBuffer, &SGUI_DEFAULT_FONT_12, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
	stDeviceInterface.fnSyncBuffer();
	printf("Flash ID: %06X.\r\n", SPI_FLASH_ReadID());
	
	/* Display time. */
	while(bExit)
	{
		/* Read key. */
		KB_Scan();
		uiKeyCode = GetTriggeredKey();
		if(KEY_NONE != uiKeyCode)
		{
			sprintf(szTextBuffer, "Pressed: 0x%02X", uiKeyCode);
		}
		else
		{
			sprintf(szTextBuffer, "Pressed: NONE");
		}
		stDisplayArea.iPosY = 16;
		SGUI_Text_DrawText(&stDeviceInterface, szTextBuffer, &SGUI_DEFAULT_FONT_12, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
		stDeviceInterface.fnSyncBuffer();
		
		if(true == RTCTimerIsTrigger())
		{
			pstNowTime = RTC_ConvertToCalendar(RTC_GetTimeStamp());
			sprintf(szTextBuffer, "DATE:%04u-%02u-%02u", pstNowTime->tm_year, pstNowTime->tm_mon, pstNowTime->tm_mday);
			stDisplayArea.iPosY = 30;
			SGUI_Text_DrawText(&stDeviceInterface, szTextBuffer, &SGUI_DEFAULT_FONT_12, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
			sprintf(szTextBuffer, "TIME:%02u:%02u:%02u", pstNowTime->tm_hour, pstNowTime->tm_min, pstNowTime->tm_sec);
			stDisplayArea.iPosY = 44;
			SGUI_Text_DrawText(&stDeviceInterface, szTextBuffer, &SGUI_DEFAULT_FONT_12, &stDisplayArea, &stPos, SGUI_DRAW_NORMAL);
			
			printf("%s", szTextBuffer);
			stDeviceInterface.fnSyncBuffer();
			printf("\r\n");
			RTCTimerTriggerReset();
		}
		if(true == UsartIsReceived())
		{
			printf("Received!\r\n");
			UsartTriggerReset();
		}
	}
	
	return 0;
}

void ConfigRTC(void)
{
	RTC_CALENDAR_STRUCT			stTime;
	
	stTime.tm_year = 2020;
	stTime.tm_mon = 2;
	stTime.tm_mday = 14;
	stTime.tm_hour = 23;
	stTime.tm_min = 16;
	stTime.tm_sec = 00;
	
	RTC_UpdateCalendar(&stTime);
}

void TimerEventProc(void)
{
	BASE_TIMER_ActiveInterrupt(TIM3, false);
	KB_Scan();
	LED_Reverse();
	BASE_TIMER_ActiveInterrupt(TIM3, true);
}

